// Feature.h: interface for the CFeature class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_FEATURE_H__51C986D3_FC84_4377_B7E4_FBCAE7C93E51__INCLUDED_)
#define AFX_FEATURE_H__51C986D3_FC84_4377_B7E4_FBCAE7C93E51__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "LXH_Data.h"
#include "Math.h" 

#define		HAMMING_WIN			0x00001
#define		HANNING_WIN			0x00002 
#define		TRIANGLE_WIN		0x00004


#define		LOWPASS_FIL			0x00001
#define		HIGHPASS_FIL		0x00002
#define		BANDPASS_FIL		LOWPASS_FIL|HIGHPASS_FIL

#define		LPC_LPC				0x00001
#define		LPC_LPCC			0x00002
#define		LPC_ACF				0x00004
#define		LPC_REF				0x00008
//-------------------------------- 
// Analysis parameters 
//-------------------------------- 
typedef struct {
	//======================
	//Signal Processing
	//======================
	int		SigP_RmvSilWinSz;		//size of analyse window : default 32 samples
	float	SigP_RmvSilCoef;			//Coefficient of threshold : default 0.3

	int		VariationStpSz;		//Number of Windows in variation : default 2
	//======================
	// LPCC related
	//======================
	int		WinSz;				// -1 : default correspond with 0.01s, you can set this parametre manually (par example : 256)
	int		StpSz;				// -1 : default correspond with 0.05s samples ( par example : 128)
	long	FType;				// feature sets, bit ORed;
	bool	PreEmphasis;		// PreEmphasis with Alpha Coef, default : true
	float	Alpha;				// preemphesis, default=0.97
	int 	Windowing;			// 0 : No windowing, HAMMING_WIN, HANNING_WIN or TRIANGLE_WIN, default : 0
	int		RmvSilence;			// 1: remove silence part, 0: intact, default : 0
	int		RmvDC;				// 1: remove DC, 0 : intact, default : 0

	int		Filtering;			// 0 : no filter, LOWPASS_FIL, HIGHPASS_FIL, BANDPASS_FIL, default : 0
	int		LowFilCutOffFreq;	// Cut Off frquence of low filter, default : 5000
	int		HighFilCutOffFreq;	// Cut Off frquence of low filter, default : 0
	int		FilOrder;			// Order of filter, default : 199

	//======================
	// extra parameter of MFCC 
	//======================
	int		SRate;	            // sampling rate of Sig;
	int		MFCC_Order;			// number of MFCC; default 12
	int		NFilter;			// number of filters in Filter bank, default : 20
	int		FFTSz;				// FFT order, default : -1 : detect automatic
	int		DEnergy;			// 1: output delta value for first MFCC (energy)
	bool	use_power_rather_than_energy; //default true;
	bool	take_log;			//default true;
	int		MFCC_Lift;			//Coeff of liftering : default 22
	bool	include_co;			//default false;

	//======================
	// extra para for Pitch 
	//======================
	int		PWinSz;				//Size of Window in Pitch determination, default 400;
	int		DownCoef;			//Coef to down Sample : default 3
	float	CutCoef;			//Coef to thresholding the pitch, default 0.3
	int		MinPit;				//Min Pitch, default 70
	int		MaxPit;				//Max Pitch, default 300
	int		Smooth;				// 1: smooth pitch contour with 3-point median filter

	//======================
	// extra para for LPC
	//======================
	int		LPC_Type;			// LPC_LPC, LPC_LPCC, LPC_ACF, LPC_REF, default : LPC_LPC
	int		LPC_Order;			// LPC order, default : 17 ( LPCo = 1 and 16 LPCi )

} PARA_TYPE;

typedef struct 
{
	float *fWin;
	int	  nSize;

	void CreateWin(int nWinSize)
	{
		fWin = (float*)calloc( nWinSize, sizeof(float) );
		if( fWin == NULL )
			ErrorMsg( "Not enough memory to alloc to struct FilterWin");
		nSize = nWinSize;
	}

	void DeleteWin()
	{
		if(fWin != NULL) 
		{
			free(fWin);
			nSize = 0;
		}
	}
	
	float &operator [] (int i) 
	{ 
		return fWin[i];
	}
} FilterWin;

typedef float * FloatVec;
typedef short * ShortVec;
#define PI		3.1415926535897932384626433832795
#define PIx2	6.283185307179586476925286766559

class CFeature  
{
protected:
	void GenHanWin(int nSize);
	int			FastFFT(float *invec, int nLen);
	void		GenHamWin(int nFSize);
	FilterWin	*fHamming;
	FilterWin	*fHanning;
	FilterWin	*fTriangle;

public:
	void NormalizeCol(CData &data);
	void Simple_Mean_Smooth(float *sig, int nSize, int nOrder);
	float * FIRhighpass_filter(float *sig, int nLen, int nSampleRat, int nCutOffFreq, int nOrder);
	void FIRhighpass_filter();
	void FIRhighpass_double_filter();
	float * FIRhighpass_double_filter(float *sig, int nLen, int nSampleRate, int nCutOffFreq, int nOrder);

	float * FIRlowpass_double_filter(float *sig, int nLen, int nSampleRate, int nCutOffFreq, int nOrder);
	void FIRlowpass_double_filter();
	void FIRlowpass_filter();
	float * FIRlowpass_filter(float *sig, int nLen, int nSampleRat, int nCutOffFreq, int nOrder);


	CData * DeltaCol(CData &DataSet);
	int IFFT(CData &pFFT);
	int IFFT(float *real, int real_len, float *imag, int imag_len);
	void Triangle(float *sig, int nLen);
	void Hanning(float *sig, int nLen);
	void GenTriWin(int nSize);
	void Window( float *s, int nSize );
	void Hamming(float *sig, int nLen);
	void PreEmphasis(float *sig, int nLen, float coef);
	CData * Signal2FFT();
	CData * Signal2FFT(const float *fSignal, const int nLen, bool use_power_than_energy = true);
	void Normalization(CData &data);
	CData * ExtractEnergy();
	short RemoveDC();
	CData * DeltaRow(CData &DataSet);
	int GetLen();
	float * GetSig();
	BOOL IsSignalLoaded();
	float MeanEnergy(float *s, int nLen);
	long RemoveSilence();
	//void PreEmphasis(FloatVec s, float PreCoef);
	//void Hamming(FloatVec lpSignal);


	void CopySignal(short *lpSignal, int nSigLen, int nSampleRate);


	//This method must be override
	virtual CData *ExtractFeature() = 0;

	PARA_TYPE	para;
	float		*fSignal;
	int			nLen;

	CFeature();
	virtual ~CFeature();
};

#endif // !defined(AFX_FEATURE_H__51C986D3_FC84_4377_B7E4_FBCAE7C93E51__INCLUDED_)
